home *** CD-ROM | disk | FTP | other *** search
/ Aminet 4 / Aminet 4 - November 1994.iso / aminet / comm / misc / avmnfaxsrc1_33.lha / asc2fax.c < prev    next >
C/C++ Source or Header  |  1994-06-24  |  10KB  |  482 lines

  1. /*
  2.  * asc2fax.c
  3.  *
  4.  * Copyright (C) 1993 by Olaf 'Rhialto' Seibert. All rights reserved.
  5.  *
  6.  * V24.05.93: Initial release
  7.  * V29.05.93: Fixed unsigned character bug
  8.  *
  9.  * $Id: asc2fax.c,v 1.2 1993/06/11 16:33:37 Rhialto Exp $
  10.  * $Log: asc2fax.c,v $
  11.  * Revision 1.2  1993/06/11  16:33:37  Rhialto
  12.  * First real RCS checkin
  13.  *
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20.  
  21. #define INTUI_V36_NAMES_ONLY
  22. #include <utility/tagitem.h>
  23. #include <intuition/intuition.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/alib_protos.h>
  26. #include <clib/graphics_protos.h>
  27. #include <clib/intuition_protos.h>
  28. #include <clib/diskfont_protos.h>
  29.  
  30. #include "faxfile.h"
  31.  
  32. #define RASTERWIDTH LINE_BITS
  33. #define ESC        "\33"
  34. #define CSI        "\233"
  35. #define uchar(x)    ((unsigned char)(x))
  36.  
  37. extern int FaxFine;
  38.  
  39. void OpenFaxFile(int);
  40. void dochar(char);
  41. int        verbose;
  42. int        xoffset = 0;
  43. int        yoffset = 0;
  44. int        invert;
  45. void           *IntuitionBase;
  46. void           *GfxBase;
  47. void           *DiskFontBase;
  48. struct BitMap    BitMap;
  49. struct RastPort EmergencyRastPort;
  50. struct RastPort *RastPort;
  51. struct Window  *Window = 0;
  52. struct TextFont *Font;
  53. struct TextFont *OldFont;
  54. struct NewWindow NewWindow = {
  55.     0, 20,            /* LeftEdge, TopEdge */
  56.     640, 0,            /* Width, Height (calculated and set) */
  57.     1, 1,            /* DetailPen, BlockPen */
  58.     0,                /* IDCMPFlags */
  59.     WFLG_SUPER_BITMAP | WFLG_GIMMEZEROZERO | WFLG_NOCAREREFRESH |
  60.     WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_SIZEGADGET | WFLG_SIZEBRIGHT, /* Flags */
  61.     NULL,            /* FirstGadget */
  62.     NULL,            /* CheckMark */
  63.     NULL,            /* Title */
  64.     NULL,            /* Screen */
  65.     &BitMap,            /* BitMap */
  66.     20,20, -1,0,        /* Min/Max Width/Height */
  67.     WBENCHSCREEN        /* Type */
  68. };
  69. struct TagItem TextTags[] = {
  70.     TA_DeviceDPI, X_DPI | Y_DPI << 16,
  71.     TAG_END
  72. };
  73.  
  74. char fontWanted[100] = "courier.font";
  75.  
  76. struct TTextAttr TextAttr = {
  77.     fontWanted, 30, FSF_TAGGED, 0, TextTags
  78. };
  79.  
  80. void
  81. meminvert(unsigned char *d, int size)
  82. {
  83.     if (((long) d & 0x01) == 0) {
  84.     while (size >= 4) {
  85.         *(long *)d ^= 0xFFFFFFFF;
  86.         d += 4;
  87.         size -= 4;
  88.     }
  89.     }
  90.     while (size > 0) {
  91.     *d++ ^= 0xFF;
  92.     size--;
  93.     }
  94. }
  95.  
  96. struct TextInfo {
  97.     struct RastPort *rp;
  98.     int         xoffset;
  99. } ti;
  100.  
  101. unsigned char  *
  102. DoText(unsigned char *text, int len)
  103. {
  104.     if (len > 0)
  105.     Text(ti.rp, text, len);
  106.     return text + len;
  107. }
  108.  
  109. unsigned char  *
  110. DoCSI(unsigned char *text)
  111. {
  112.     int         arg[8];
  113.     int         narg = 0;
  114.     int         i;
  115.  
  116.     memset(arg, 0, sizeof(arg));
  117.     /* CSI 0 x and CSI x are indistinguishable */
  118.     for(;;text++) {
  119.     while (isdigit(text[0])) {
  120.         if (narg < 8) {
  121.         arg[narg] *= 10;
  122.         arg[narg] += text[0] - '0';
  123.         }
  124.         text++;
  125.     }
  126.     narg++;
  127.     if (text[0] != ';')
  128.         break;
  129.     }
  130.     if (narg > 8)
  131.     narg = 8;
  132.  
  133.     switch (*text++) {
  134.     case 'm':   /* Select graphic rendition */
  135.     for (i = 0; i < narg; i++) {
  136.         switch (arg[i]) {
  137.         case 0:    /* plain */
  138.         SetSoftStyle(ti.rp, FS_NORMAL, FSF_BOLD|FSF_ITALIC|FSF_UNDERLINED);
  139.         SetDrMd(ti.rp, JAM1);
  140.         break;
  141.         case 1:    /* bold */
  142.         SetSoftStyle(ti.rp, FSF_BOLD, FSF_BOLD);
  143.         break;
  144.         case 3:    /* italic */
  145.         SetSoftStyle(ti.rp, FSF_ITALIC, FSF_ITALIC);
  146.         break;
  147.         case 4:    /* underline */
  148.         SetSoftStyle(ti.rp, FSF_UNDERLINED, FSF_UNDERLINED);
  149.         break;
  150.         case 7:    /* inverse video */
  151.         SetDrMd(ti.rp, JAM1 | INVERSVID);
  152.         break;
  153.         case 22:     /* not bold */
  154.         SetSoftStyle(ti.rp, 0, FSF_BOLD);
  155.         break;
  156.         case 23:     /* not italic */
  157.         SetSoftStyle(ti.rp, 0, FSF_ITALIC);
  158.         break;
  159.         case 24:     /* not underline */
  160.         SetSoftStyle(ti.rp, 0, FSF_UNDERLINED);
  161.         break;
  162.         case 27:     /* not inverse video */
  163.         SetDrMd(ti.rp, JAM1);
  164.         break;
  165.         }
  166.     }
  167.     break;
  168.     case 'x':           /* set left offset */
  169.     ti.xoffset = arg[0];
  170.     break;
  171.     }
  172.  
  173.     return text;
  174. }
  175.  
  176. unsigned char  *
  177. DoCtrl(unsigned char *text)
  178. {
  179.     switch (*text++) {
  180.     case '\t':          /* tab */
  181.     {
  182.         int         charpos;
  183.  
  184.         charpos = (ti.rp->cp_x - ti.xoffset) / ti.rp->TxWidth;
  185.         charpos = (charpos + 8) & ~7;
  186.         Move(ti.rp, ti.xoffset + charpos * ti.rp->TxWidth, ti.rp->cp_y);
  187.     }
  188.     break;
  189.     case '\n':          /* newline */
  190.     Move(ti.rp, ti.xoffset, ti.rp->cp_y + ti.rp->TxHeight);
  191.     break;
  192.     case '\f':          /* formfeed */
  193.     SetRast(ti.rp, 0);
  194.     Move(ti.rp, ti.xoffset, ti.rp->TxBaseline);
  195.     break;
  196.     case uchar('\233'): /* control sequence introducer */
  197.     goto csi;
  198.     case '\033':        /* escape */
  199.     switch (*text++) {
  200.     case '#':
  201.       text++;
  202.       break;
  203.     case 'c':       /* reset */
  204.         ti.xoffset = 0;
  205.         ti.rp->Mask = 0x0001;
  206.         SetAPen(ti.rp, 1);
  207.         SetBPen(ti.rp, 0);
  208.         DoCtrl("\f");
  209.         DoCSI("0m");
  210.         break;
  211.     case '[':       /* CSI */
  212.     csi:
  213.         text = DoCSI(text);
  214.         break;
  215.     }
  216.     break;
  217.     }
  218.  
  219.     return text;
  220. }
  221.  
  222. void
  223. WinWrite(unsigned char *text)
  224. {
  225.     while (*text) {
  226.     unsigned char  *p;
  227.     int        len;
  228.  
  229.     /* First, determine how much real text we have */
  230.     for (len = 0, p = text; isprint(*p); p++) {
  231.         len++;
  232.     }
  233.     text = DoText(text, len);
  234.     if (*text && !isprint(*text))
  235.         text = DoCtrl(text);
  236.     }
  237. }
  238.  
  239. void WinWriteInit(void)
  240. {
  241.     ti.rp = RastPort;
  242.     DoCtrl(ESC"c");
  243. }
  244.  
  245. static int cp = 0;
  246.  
  247. void finalizeDoChar(void) {
  248.   if (cp) dochar('\n');
  249. }
  250.  
  251. void initializeDoChar(void) {
  252.   cp = 0;
  253. }
  254.  
  255. void dochar(char c) {
  256.   static unsigned char line[512];
  257.   extern void* FaxHandle;
  258.   unsigned char  *plane;
  259.   struct RastPort *rp = RastPort;
  260.   int i;
  261.  
  262.   switch (c) {
  263.   case 0:
  264.     break;
  265.   case '\r':
  266.     /* printf("Got <cr>\n"); */
  267.     break;
  268.   case '\n':
  269.     line[cp] = '\0';
  270.     /* printf("line=%s\n", line); */
  271.  
  272.     if (!FaxHandle) {
  273.       OpenFaxFile(1); /* signal that we started printing text first */
  274.     }
  275.  
  276.     WinWrite("\f");
  277.     WinWrite(line);
  278.     if (Window)
  279.       SyncSBitMap(rp->Layer);
  280.     plane = BitMap.Planes[0];
  281.  
  282.     if (FaxHandle) {
  283.       for (i = 0; i < Font->tf_YSize; i++) {
  284.     if (invert)
  285.       meminvert(plane, BitMap.BytesPerRow);
  286.     tofax(FaxHandle, plane, RASTERWIDTH);
  287.     plane += BitMap.BytesPerRow;
  288.     if (!FaxFine) {
  289.       plane += BitMap.BytesPerRow; /* decimate -- skip the next row */
  290.       i++;
  291.     }
  292.       }
  293.     }
  294.     cp = 0;
  295.     break;
  296.   default:
  297.     // printf("dochar('%c')\n", c);
  298.     line[cp++] = c;
  299.     break;
  300.   }
  301. }
  302.  
  303. void
  304. openall(void)
  305. {
  306.   char* userDefinedFont = 0;
  307.   char* userDefinedFontSize = 0;
  308.  
  309.   /* Libraries */
  310.   IntuitionBase = OpenLibrary("intuition.library", 33);
  311.   if (IntuitionBase == NULL) {
  312.     printf("Needs intuition V33+.\n");
  313.     exit(10);
  314.   }
  315.   GfxBase = OpenLibrary("graphics.library", 33);
  316.   if (GfxBase == NULL) {
  317.     printf("Needs gfx V33+.\n");
  318.     exit(10);
  319.   }
  320.   DiskFontBase = OpenLibrary("diskfont.library", 34);
  321.   if (DiskFontBase == NULL) {
  322.     printf("Needs diskfont V34+.\n");
  323.     exit(10);
  324.   }
  325.   
  326.   userDefinedFont = (char*)getenv("AVMFAXFONT");
  327.   userDefinedFontSize = (char*)getenv("AVMFAXFONTSIZE");
  328.   
  329.   if (userDefinedFont) strcpy(fontWanted, userDefinedFont);
  330.   if (userDefinedFontSize) TextAttr.tta_YSize = atoi(userDefinedFontSize);
  331.  
  332.   /* Font for window; sorry for the strange order */
  333.   printf("Opening DiskFont... (This may take a while)\n");
  334.   Font = OpenDiskFont((struct TextAttr *)&TextAttr);
  335.   if (Font == NULL) {
  336.     printf("No font %s/%d!\n", TextAttr.tta_Name, TextAttr.tta_YSize);
  337.     
  338.     strcpy(fontWanted, "CGTimes.font");
  339.     printf("Opening CGTimes DiskFont... (This may take a while)\n");
  340.  
  341.     Font = OpenDiskFont((struct TextAttr*)&TextAttr);
  342.     if (Font == NULL) {
  343.       printf("No font %s/%d!\n", TextAttr.tta_Name, TextAttr.tta_YSize);
  344.       printf("Cannot contuine.\n");
  345.       exit(10);
  346.     }
  347.   }
  348.  
  349.   NewWindow.Height = Font->tf_YSize + 16;  /* slight safety fudge */
  350.   /* Raster for text */
  351.   InitBitMap(&BitMap, 1, RASTERWIDTH, NewWindow.Height);
  352.   if ((BitMap.Planes[0] = AllocRaster(RASTERWIDTH, NewWindow.Height)) == NULL) {
  353.     printf("No plane\n");
  354.     exit(10);
  355.       }
  356.   /* Window for raster. For showing-off purposes only. */
  357.   
  358. #if 0
  359.     if ((Window = OpenWindow(&NewWindow)) == NULL) {
  360.     printf("No window (probably too large). Will do without.\n");
  361.     }
  362. #else
  363.     Window = 0;
  364. #endif
  365.  
  366.     if (Window) {
  367.     RastPort = Window->RPort;
  368.     } else {
  369.     RastPort = &EmergencyRastPort;
  370.     InitRastPort(RastPort);
  371.     RastPort->BitMap = &BitMap;
  372.     }
  373.     RastPort->Mask = 0x0001;
  374.     OldFont = RastPort->Font;
  375.     SetFont(RastPort, Font);
  376. }
  377.  
  378.  
  379. /*
  380.  * Clean up system stuff in case of exit
  381.  */
  382. void
  383. cleanup(void)
  384. {
  385.     if (Font) {
  386.     SetFont(RastPort, OldFont);
  387.     CloseFont(Font);
  388.     }
  389.     if (Window) {
  390.     CloseWindow(Window);
  391.     }
  392.     if (GfxBase) {
  393.     if (BitMap.Planes[0]) {
  394.         FreeRaster(BitMap.Planes[0], RASTERWIDTH, NewWindow.Height);
  395.         BitMap.Planes[0] = NULL;
  396.     }
  397.     CloseLibrary(GfxBase);
  398.     }
  399.     if (IntuitionBase) {
  400.     CloseLibrary(IntuitionBase);
  401.     }
  402.     if (DiskFontBase) {
  403.     CloseLibrary(DiskFontBase);
  404.     }
  405. }
  406.  
  407. /*
  408. int
  409. main(int argc, char **argv)
  410. {
  411.     char       *outfile = "ascii.g3";
  412.     struct faxout  *faxp;
  413.     int         rawfax = 1;
  414.     int         append = 0;
  415.     extern char    *optarg;
  416.     extern int        optind;
  417.     extern int        getopt(int, char **, char *);
  418.     int         errflg = 0;
  419.     int         c;
  420.  
  421.     while ((c = getopt(argc, argv, "af:io:rs:vx:y:")) != -1) {
  422.     switch (c) {
  423.     case 'a':
  424.         append = 1;
  425.         break;
  426.     case 'f':
  427.         TextAttr.tta_Name = optarg;
  428.         break;
  429.     case 's':
  430.         TextAttr.tta_YSize = atoi(optarg);
  431.         break;
  432.     case 'i':
  433.         invert = 1;
  434.         break;
  435.     case 'o':
  436.         outfile = optarg;
  437.         break;
  438.     case 'r':
  439.         rawfax++;
  440.         break;
  441.     case 'v':
  442.         verbose = TRUE;
  443.         break;
  444.     case 'x':
  445.         xoffset = atoi(optarg);
  446.         break;
  447.     case 'y':
  448.         yoffset = atoi(optarg);
  449.         break;
  450.     case '?':
  451.         errflg++;
  452.         break;
  453.     }
  454.     }
  455.  
  456.     if (errflg || optind >= argc) {
  457.     printf(
  458. "Usage: asc2fax [-o fax-file (ascii.g3)] [-r raw faxfile] [-a (append)]\n"
  459. "               [-x/y x/y-offset (50)] [-v] [-i (invert)]\n"
  460. "               [-f name.font] [-s fontsize] ascii-files\n");
  461.     exit(EXIT_FAILURE);
  462.     }
  463.  
  464.     atexit(cleanup);
  465.     openall();
  466.  
  467.     faxp = faxout_open_fp(fopen(outfile, append? "ab": "wb"), rawfax);
  468.     if (faxp == NULL) {
  469.         // fprintf(stderr, "can't open output file %s.\n", outfile);
  470.     goto fail;
  471.     }
  472.  
  473.     while (optind < argc) {
  474.     dofile(argv[optind], faxp);
  475.     optind++;
  476.     }
  477.  
  478.     faxout_close(faxp);
  479. fail:
  480. }
  481. */
  482.